/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.tchepannou.limbe.mock.servlet;

import com.tchepannou.util.IOUtil;
import com.tchepannou.util.MimeUtil;

import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;

/**
 *
 * @author herve
 */
public class MockServletContext
    implements ServletContext
{
    public static final int VERSION_MAJOR = 2;
    public static final int VERSION_MINOR = 4;

    //-- Attribute
    //private String _path;
    private ResourceLocator _locator = new ClasspathResourceLocator ();
    private Map<String, String> _parameters = new HashMap<String, String> ();
    private Map<String, Object> _attributes = new HashMap<String, Object> ();

    //-- Constructor
    public MockServletContext ()
    {
    }
    public MockServletContext (ResourceLocator locator)
    {
        _locator = locator;
    }

    //-- Public
    public void setInitParameter(String name, String value)
    {
        _parameters.put (name, value);
    }

    //-- ServletContext overrides
    public ServletContext getContext (String uripath)
    {
        return new MockServletContext ();
    }

    public int getMajorVersion ()
    {
        return VERSION_MAJOR;
    }

    public int getMinorVersion ()
    {
        return VERSION_MINOR;
    }

    public String getMimeType (String file)
    {
        return MimeUtil.getInstance ().getMimeTypeByFile (file);
    }

    public Set getResourcePaths (String path)
    {
        return new HashSet ();
    }

    public URL getResource (String path)
        throws MalformedURLException
    {
        String xpath = getRealPath (path);
        return xpath != null ? new URL ("file:" + xpath) : null;
    }

    public InputStream getResourceAsStream (String path)
    {
        try
        {
            String xpath = getRealPath (path);
            if (xpath != null)
            {
                File file = new File(xpath);
                ByteArrayOutputStream out = new ByteArrayOutputStream ();
                IOUtil.copy(file, out);
                return new ByteArrayInputStream(out.toByteArray());
            }
            else
            {
                return null;
            }
        }
        catch(IOException e)
        {
            return null;
        }
    }

    public RequestDispatcher getRequestDispatcher (String path)
    {
        return null;
    }

    public RequestDispatcher getNamedDispatcher (String name)
    {
        return null;
    }

    public Servlet getServlet (String name)
        throws ServletException
    {
        return null;
    }

    public Enumeration getServlets ()
    {
        return null;
    }

    public Enumeration getServletNames ()
    {
        return null;
    }

    public void log (String msg)
    {
        System.out.println (msg);
    }

    public void log (Exception exception, String msg)
    {
        System.out.println (msg);
        exception.printStackTrace ();
    }

    public void log (String msg, Throwable throwable)
    {
        System.out.println (msg);
        throwable.printStackTrace ();
    }

    public String getRealPath (String path)
    {
        return _locator.locate (path);
    }

    public String getServerInfo ()
    {
        return getClass ().getName ();
    }

    public String getInitParameter (String name)
    {
        return _parameters.get (name);
    }

    public Enumeration getInitParameterNames ()
    {
        return new Vector (_parameters.keySet ()).elements ();
    }

    public Object getAttribute (String name)
    {
        return _attributes.get (name);
    }

    public Enumeration getAttributeNames ()
    {
        return  new Vector (_attributes.keySet ()).elements ();
    }

    public void setAttribute (String name, Object object)
    {
        _attributes.put (name, object);
    }

    public void removeAttribute (String name)
    {
        _attributes.remove (name);
    }

    public String getServletContextName ()
    {
        return "";
    }
    
    
    //-- Innerr class
    public static interface ResourceLocator
    {
        public String locate (String path);
    }
    
    public static class WebResourceLocator
        implements ResourceLocator
    {
        private String _basePath;
        
        public WebResourceLocator ()
        {
            URL url = getClass ().getResource ("/");
            String xpath = url.toString () + "../..";
            _basePath = xpath.startsWith ("file:") ? xpath.substring (5) : xpath;
        }
        public String locate (String path)
        {
            if (!path.startsWith ("/") )
            {
                path = "/" + path;
            }
            return _basePath + path;
        }
    }
    public static class ClasspathResourceLocator
        implements ResourceLocator
    {
        public String locate (String path)
        {
            if (!path.startsWith ("/") )
            {
                path = "/" + path;
            }
            String xpath = null;
            URL url = getClass ().getResource (path);
            if (url != null)
            {
                xpath = url.toString ();
                xpath = xpath.startsWith ("file:") ? xpath.substring (5) : xpath;                                
            }
            return xpath;
        }
    }    
}
